package com.wontube.smr.web.controller.admin;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.wontube.client.extension.utils.StringUtils;
import com.wontube.client.remote.Remoting;
import com.wontube.smr.client.model.po.Country;
import com.wontube.smr.client.model.po.WebsiteCategory;
import com.wontube.smr.client.model.po.WebsiteLink;
import com.wontube.smr.web.client.admin.IAdminWebsiteLinkHandler;

/**
 * 
 * @author LuoBiao
 *
 */
@Controller
@RequestMapping(value = "/admin/website", method = RequestMethod.GET)
public class AdminWebsiteLinkController {
	private final static String SUCCESS = "Done";
	private final static String FAILURE = "Failure: something wrong";

	@RequestMapping("")
	public ModelAndView website_home(){
		ModelAndView mv = new ModelAndView("admin/website/website_index");
		IAdminWebsiteLinkHandler handler = getWebsiteLinkHandler();
		Object[] objs = handler.listWebsiteCategoryAndCountries();		
		mv.addObject("categoryList", objs[0]);		
		mv.addObject("countries", objs[1]);	
		return mv;
	}
	
	@RequestMapping("/list")
	public ModelAndView list_website_links(
			@RequestParam(value="sysId", required=false) String sysId,
			@RequestParam("countryCode") String countryCode, 
			@RequestParam(value="category", required=false) String category){
		ModelAndView mv = new ModelAndView("admin/website/website_list");
		IAdminWebsiteLinkHandler handler = getWebsiteLinkHandler();
		List<WebsiteLink> websites = handler.listWebsiteLinks(countryCode, sysId, category);
		mv.addObject("websiteList", websites);
		return mv;
	}
	
	@RequestMapping("/get/{id}")
	public ModelAndView getWebsiteLink(@PathVariable("id") String id){
		ModelAndView mv = new ModelAndView("admin/website/update_website");
		IAdminWebsiteLinkHandler handler = getWebsiteLinkHandler();
		WebsiteLink website = handler.getWebsiteLinkByPK(id);
		mv.addObject("website", website);
		Object[] objs = handler.listWebsiteCategoryAndCountries();		
		mv.addObject("categoryList", objs[0]);		
		mv.addObject("countries", objs[1]);	
		return mv;
	}
	
	@RequestMapping(value="/update", method=RequestMethod.POST)
	@ResponseBody
	public String updateWebsiteLink(WebsiteLink link){
		IAdminWebsiteLinkHandler handler = getWebsiteLinkHandler();
		boolean success = handler.saveOrUpdateWebsiteLink(link);
		if(success){
			return SUCCESS;
		}
		return FAILURE;
	}
	
	@RequestMapping(value="/add", method=RequestMethod.POST)
	@ResponseBody
	public String addWebsiteLink(WebsiteLink website){
		IAdminWebsiteLinkHandler handler = getWebsiteLinkHandler();
		website.setId(UUID.randomUUID().toString());
		boolean success = handler.saveOrUpdateWebsiteLink(website);
		if(success){
			return SUCCESS;
		}
		return FAILURE;
	}
	
	@RequestMapping("/delete/{id}")
	@ResponseBody
	public String deleteWebsiteLink(@PathVariable("id") String id){
		IAdminWebsiteLinkHandler handler = getWebsiteLinkHandler();		
		boolean success = handler.deleteWebsiteLink(id);
		if(success){
			return SUCCESS;
		}
		return FAILURE;
	}
	
	@RequestMapping("/clean")
	@ResponseBody
	public String deleteCaches() {	
		Remoting<IAdminWebsiteLinkHandler> remoting = new Remoting<IAdminWebsiteLinkHandler>();
		IAdminWebsiteLinkHandler handler = remoting.createService(IAdminWebsiteLinkHandler.class);
		handler.clearDeviceCaches();
		
		if(remoting.isDone()){
			return SUCCESS;
		}else{
			return remoting.getLastErrMsg();
		}
	}		
	
	private IAdminWebsiteLinkHandler getWebsiteLinkHandler(){
		Remoting<IAdminWebsiteLinkHandler> remoting = new Remoting<IAdminWebsiteLinkHandler>();
		IAdminWebsiteLinkHandler handler = remoting.createService(IAdminWebsiteLinkHandler.class);
		return handler;
	}
	
	@RequestMapping(value="/cat/add", method=RequestMethod.POST)
	@ResponseBody
	public String addWebsiteCategory(WebsiteCategory cat){
		if(StringUtils.isNullOrEmpty(cat.getCategoryName())){
			return "Category Name cannot be empty";
		}
		
		if(StringUtils.isNullOrEmpty(cat.getCountryCode())){
			return "Category Country Code cannot be empty";
		}
		
		IAdminWebsiteLinkHandler handler = getWebsiteLinkHandler();
		cat.setId(UUID.randomUUID().toString());
		boolean success = handler.saveOrUpdateWebsiteCategory(cat);
		if(success){
			return SUCCESS;
		}
		return FAILURE;
	}
	
	@RequestMapping("/cat/delete/{id}")
	@ResponseBody
	public String deleteWebsiteCategory(@PathVariable("id") String id){
		IAdminWebsiteLinkHandler handler = getWebsiteLinkHandler();		
		boolean success = handler.deleteWebsiteCategory(id);
		if(success){
			return SUCCESS;
		}
		return FAILURE;
	}	
	
	
	@RequestMapping(value="/country/add",  method=RequestMethod.POST)
	@ResponseBody
	public String add_country(Country country){
		if(StringUtils.isNullOrEmpty(country.getCountryCode())){
			return "Country Code is Null";
		}
		if(StringUtils.isNullOrEmpty(country.getCountryName())){
			return "Country Name is Null";
		}
		country.setId(UUID.randomUUID().toString());
		IAdminWebsiteLinkHandler handler = getWebsiteLinkHandler();
		int aff = handler.addCountry(country);
		if(aff == 1){
			return SUCCESS;
		}
		return FAILURE;
	}
	
	@RequestMapping(value="/country/delete/{id}", method=RequestMethod.POST)
	@ResponseBody
	public String delete_country(@PathVariable("id") String id){
		IAdminWebsiteLinkHandler handler = getWebsiteLinkHandler();
		int aff = handler.deleteCountry(id);
		if(aff == 1){
			return SUCCESS;
		}
		return FAILURE;
	}
	
	/**
	 * 
	 * @param uploadPath
	 * @return
	 */
	@RequestMapping("/upload")	
	public ModelAndView upload(@Value("${uploadPath}") String uploadPath){		
		ModelAndView mv = new ModelAndView("admin/website/upload/upload_index");
		File dir = new File(uploadPath.trim());							
		File[] files = dir.listFiles();
		if(files != null){
			sortFiles(files);
		}		
		mv.addObject("files", files);		
		mv.addObject("parent", "");
		return mv;
	}
	
	/**
	 * @param uploadPath
	 * @param dir
	 * @return
	 */
	@RequestMapping("/upload/unfold")
	public ModelAndView unfold(@Value("${uploadPath}") String uploadPath, 
			@RequestParam("dir") String dir){
		ModelAndView mv = new ModelAndView("admin/website/upload/unfold_file_list");
		File root = new File(uploadPath.trim() + dir);
		if(root.isDirectory()){
			File[] files = root.listFiles();
			sortFiles(files);
			mv.addObject("parent", dir);
			mv.addObject("files", files);	
		}
			
		return mv;
	}
	
	@RequestMapping(value="/upload/delete", method=RequestMethod.POST)
	@ResponseBody
	public String delete_upload(@Value("${uploadPath}") String uploadPath, 
			@RequestParam("dir") String dir){
		File file = new File(uploadPath.trim() + dir);
		int aff = deleteFiles(file);
		return aff + "";
	}
	
	@RequestMapping(value="/upload/mkdir", method=RequestMethod.POST)
	@ResponseBody
	public String mkdir(@Value("${uploadPath}") String uploadPath, 
			@RequestParam("parent") String parent, @RequestParam("dir") String dir){
		String[] dirs = dir.split("/");
		String path = uploadPath.trim() + parent;
		int aff = 0;
		for (String d : dirs) {
			if( ! "".equals(d)){
				path += "/" + d;
				File file = new File(path);
				if( ! file.exists()){
					if(file.mkdir()){
						aff += 1;
					}
				}
			}
		}
		return aff + "";
	}
	
	@RequestMapping(value="/upload/files", method=RequestMethod.POST)
	@ResponseBody
	public String upload_files(@Value("${uploadPath}") String uploadPath, 
			@RequestParam("parent") String parent,	@RequestParam("file") MultipartFile file){
		String filename = file.getOriginalFilename();
		File tf = new File(uploadPath.trim() + parent + "/" + filename);
		if(tf.exists()){
			return "Fail: File exists";
		}else{
			FileOutputStream fos = null;
			try {				
				fos = new FileOutputStream(tf);
				fos.write(file.getBytes());
			} catch (Exception e) {
				return "Fail: error happen when write to file";
			} finally {
				if(fos != null){
					try {
						fos.close();
					} catch (Exception e2) {						
					}					
				}
			}
		}
		return "Done";
	}	
	
	private int deleteFiles(File file){
		int aff = 0;
		if(file.isDirectory()){
			File[] files = file.listFiles();
			if(files.length == 0){
				if(file.delete()){
					aff += 1;
				}
			}else{
				for (File file2 : files) {
					aff += deleteFiles(file2);
				}
				//delete youself
				if(file.delete()){
					aff += 1;
				}
			}		
		}else{
			if(file.delete()){
				aff += 1;
			}
		}
		return aff;
	}
	
	private void sortFiles(File[] files){
		Arrays.sort(files, new Comparator<File>() {
			@Override
			public int compare(File o1, File o2) {
				if(o1.isDirectory()){
					if( ! o2.isDirectory()){
						return -1;
					}
				}else{
					if(o2.isDirectory()){
						return 1;
					}
				}
				return 0;
			}				
		});
	}
}
